﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using System.Net.Sockets;
using System.Threading;
using Microsoft.Phone.Shell;

namespace eHouse
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            RefreshImage.ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri("Refresh" + App.IconToUse + ".png", UriKind.RelativeOrAbsolute));
            ScheduleImage.ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri("Schedule" + App.IconToUse + ".png", UriKind.RelativeOrAbsolute));
            AboutImage.ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri("About" + App.IconToUse + ".png", UriKind.RelativeOrAbsolute));

            DataContext = App.ViewModel;
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        // Load data for the ViewModel Items
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            fadeAnimation.Stop();
            Storyboard.SetTarget(fadeAnimation, PopupBorder);
            Storyboard.SetTargetProperty(fadeIn, new PropertyPath(UIElement.OpacityProperty));
            Storyboard.SetTargetProperty(fadeOut, new PropertyPath(UIElement.OpacityProperty));
            fadeOut.Completed += new EventHandler((object o, EventArgs args) =>
            {
                ToastPopup.IsOpen = false;
            });
        }

        private void SensorPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var t = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                     from type in assembly.GetTypes()
                     where type.Name == "Schedule" + ((PivotItem)SensorPivot.SelectedItem).Header.ToString()
                     select type).FirstOrDefault();

            if (t == null)
            {
                schedule.IsEnabled = false;
            }
            else
            {
                schedule.IsEnabled = true;
            }
        }

        private void schedule_Click(object sender, RoutedEventArgs e)
        {
            string sensor = ((PivotItem)SensorPivot.SelectedItem).Header.ToString();
            App.SchedulingSensor = sensor;

            Dispatcher.BeginInvoke(() =>
            {
                WaitingScreen.nextWindow = "/RulePage.xaml";
                WaitingScreen.waitingTask = new WaitingScreen.WaitingTask(() =>
                {
                    App.RuleModel.LoadRules(sensor);
                });
                NavigationService.Navigate(new Uri("/WaitingScreen.xaml", UriKind.RelativeOrAbsolute));
            });

        }

        private Brush closed = new SolidColorBrush(Color.FromArgb(255, 27, 161, 225));
        private Brush open = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));

        private void ToggleSwitch_Loaded(object sender, RoutedEventArgs e)
        {
            if ((bool)((ToggleSwitch)sender).IsChecked)
            {
                ((ToggleSwitch)sender).Content = "Open  ";
                ((ToggleSwitch)sender).SwitchForeground = open;
            }
            else
            {
                ((ToggleSwitch)sender).Content = "Closed";
                ((ToggleSwitch)sender).Background = closed;
            }
        }

        private readonly object _lock = new object();
        Storyboard fadeAnimation = new Storyboard();
        DoubleAnimation fadeIn = new DoubleAnimation()
        {
            Duration = new Duration(TimeSpan.FromMilliseconds(500)),
            From = 0.00,
            To = 1.00
        };
        DoubleAnimation fadeOut = new DoubleAnimation()
        {
            Duration = new Duration(TimeSpan.FromMilliseconds(500)),
            From = 1.00,
            To = 0.00
        };

        private void ToggleSwitch_Click(object sender, RoutedEventArgs e)
        {
            ToggleSwitch toggle = ((ToggleSwitch)sender);
            string sensor = ((PivotItem)SensorPivot.SelectedItem).Header.ToString();
            string tag = (string)toggle.Tag;
            bool isChecked = (bool)toggle.IsChecked;
            bool change = false;

            toggle.IsEnabled = false;

            EventHandler<SocketAsyncEventArgs> onServerRespondedListener =
                new EventHandler<SocketAsyncEventArgs>((object o, SocketAsyncEventArgs async) =>
                {
                    string message;

                    if (async.SocketError == SocketError.Success)
                    {
                        switch (sensor)
                        {
                            case "Lights": message = tag + " light correctly turned " + (isChecked ? "ON" : "OFF"); break;
                            case "Temperature": message = tag + " correctly turned " + (isChecked ? "ON" : "OFF"); break;
                            case "Irrigation": message = "Irrigation correctly turned " + (isChecked ? "ON" : "OFF"); break;
                            default: return;
                        }
                    }
                    else
                    {
                        change = true;

                        message = "An ERROR occurred when turning the ";
                        switch (sensor)
                        {
                            case "Lights": message += tag + " light " + (isChecked ? "ON" : "OFF"); break;
                            case "Temperature": message += tag + " " + (isChecked ? "ON" : "OFF"); break;
                            case "Irrigation": message += "irrigation " + (isChecked ? "ON" : "OFF"); break;
                            default: message = "An error occurred switching the sensor"; break;
                        }
                        message += ". Please, try again later";
                    }

                    Thread t = new Thread(() =>
                    {
                        lock (_lock)
                        {
                            Dispatcher.BeginInvoke(() =>
                                                {
                                                    fadeAnimation.Stop();
                                                    fadeAnimation.Children.Clear();
                                                    fadeAnimation.Children.Add(fadeIn);

                                                    if (change)
                                                    {
                                                        toggle.IsChecked = !toggle.IsChecked;
                                                    }
                                                    toggle.IsEnabled = true;

                                                    ToastMessage.Text = message;
                                                    ToastPopup.IsOpen = true;

                                                    fadeAnimation.Begin();
                                                });
                            Thread.Sleep(2500);
                            Dispatcher.BeginInvoke(() =>
                                                {
                                                    fadeAnimation.Stop();
                                                    fadeAnimation.Children.Clear();
                                                    fadeAnimation.Children.Add(fadeOut);
                                                    fadeAnimation.Begin();
                                                });
                            Thread.Sleep(500);
                        }
                    });
                    t.Name = "Toast control";
                    t.Start();
                });

            new Thread(() =>
            {
                App.ConnectionManager.SwitchSensor(sensor.ToUpper(),
                                tag.ToUpper(),
                                isChecked,
                                onServerRespondedListener);
            }).Start();
        }

        private void refresh_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
            {
                WaitingScreen.nextWindow = "/MainPage.xaml";
                WaitingScreen.waitingTask = new WaitingScreen.WaitingTask(() =>
                {
                    App.ViewModel.LoadData();
                    Dispatcher.BeginInvoke(() =>
                    {
                        NavigationService.RemoveBackEntry();
                    });
                });
                NavigationService.Navigate(new Uri("/WaitingScreen.xaml", UriKind.RelativeOrAbsolute));
            });
        }

        private void about_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
            {
                NavigationService.Navigate(new Uri("/AboutPage.xaml", UriKind.RelativeOrAbsolute));
            });
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            WaitingScreen.savedWindow = "/MainPage.xaml";
            base.OnNavigatedTo(e);
        }
    }
}